pull: Also skip partial commits for deltas if no summary file
authorColin Walters <walters@verbum.org>
Wed, 15 Mar 2017 16:13:58 +0000 (12:13 -0400)
committerAtomic Bot <atomic-devel@projectatomic.io>
Mon, 27 Mar 2017 17:51:11 +0000 (17:51 +0000)
I was playing around in a FAH vagrant box, and hit:

```
Receiving delta parts: 3/4 453.2 kB/s 1.8 MB/145.8 MB
error: opcode set-read-source: No such file object b6e54ba3471b9c116ce6b9bfbf9e55fec60d35cfdb9ae5ae1ee219af02a591b7
```

This is because this host version doesn't yet have
https://github.com/ostreedev/ostree/pull/710
which incidentally fixed this for the case where the OS vendor is using
summary files.

Some organizations may not be using summary files - at least we still try to
support that case. So let's copy the logic very recently added in that commit to
handle the legacy case too.

No new tests since this is a nice-to-have - we really do
expect people to be using summary files now.

Closes: #739
Approved by: jlebon

src/libostree/ostree-repo-pull.c

index ec085a81feed76ac7fac8296c3ab627337931881..b7be8a95012b78d0218cffac117807f9f875529f 100644 (file)
@@ -1197,6 +1197,14 @@ gpg_verify_unwritten_commit (OtPullData         *pull_data,
   return TRUE;
 }
 
+static gboolean
+commitstate_is_partial (OtPullData   *pull_data,
+                        OstreeRepoCommitState commitstate)
+{
+  return pull_data->legacy_transaction_resuming
+    || (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) > 0;
+}
+
 static gboolean
 scan_commit_object (OtPullData         *pull_data,
                     const char         *checksum,
@@ -1253,8 +1261,7 @@ scan_commit_object (OtPullData         *pull_data,
     goto out;
 
   /* If we found a legacy transaction flag, assume all commits are partial */
-  is_partial = pull_data->legacy_transaction_resuming
-    || (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) > 0;
+  is_partial = commitstate_is_partial (pull_data, commitstate);
 
   /* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */
   g_variant_get_child (commit, 1, "@ay", &parent_csum);
@@ -3242,6 +3249,7 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
       g_autofree char *from_revision = NULL;
       const char *ref = key;
       const char *to_revision = value;
+      gboolean have_valid_from_commit = TRUE;
 
       /* If we have a summary, find the latest local commit we have
        * to use as a from revision for static deltas.
@@ -3257,9 +3265,27 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
           if (!ostree_repo_resolve_rev (pull_data->repo, ref, TRUE,
                                         &from_revision, error))
             goto out;
+
+          /* Determine whether the from revision we have is partial; this
+           * can happen if e.g. one uses `ostree pull --commit-metadata-only`.
+           * This mirrors the logic in get_best_static_delta_start_for().
+           */
+          if (from_revision)
+            {
+              OstreeRepoCommitState from_commitstate;
+
+              if (!ostree_repo_load_commit (pull_data->repo, from_revision, NULL,
+                                            &from_commitstate, error))
+                goto out;
+
+              /* Was it partial?  OK, we can't use it. */
+              if (commitstate_is_partial (pull_data, from_commitstate))
+                have_valid_from_commit = FALSE;
+            }
         }
 
       if (!disable_static_deltas &&
+          have_valid_from_commit &&
           (from_revision == NULL || g_strcmp0 (from_revision, to_revision) != 0))
         {
           g_autofree char *delta_name =